package licode.unisop.provider.utils;

import java.time.*;
import java.time.chrono.Era;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.UnsupportedTemporalTypeException;

public class PluginUtil {
    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static boolean  isBlank(CharSequence str) {
        int length;
        if (str != null && (length = str.length()) != 0) {
            for(int i = 0; i < length; ++i) {
                if (!isBlankChar(str.charAt(i))) {
                    return false;
                }
            }
        }
        return true;
    }

    public static boolean isNotBlank(CharSequence str) {
        return !PluginUtil.isBlank(str);
    }

    public static boolean isEmpty(CharSequence str) {
        return str == null || str.length() == 0;
    }

    public static boolean isNotEmpty(CharSequence str) {
        return !PluginUtil.isEmpty(str);
    }

    public static boolean isBlankChar(char c) {
        return isBlankChar((int)c);
    }

    public static boolean isBlankChar(int c) {
        return Character.isWhitespace(c) ||
                Character.isSpaceChar(c) ||
                c == 65279 || c == 8234 || c == 0 ||
                c == 12644 || c == 10240;
    }

    public static boolean isEmoji(char c) {
        return c != 0 && c != '\t' && c != '\n'
                && c != '\r' && (c < ' ' || c > '\ud7ff') &&
                (c < '\ue000' || c > '�') && (c < 1048576 || c > 1114111);
    }

    public static String formatDateTime(LocalDateTime time) {
        return formatDateTime(time, NORM_DATETIME_PATTERN);
    }

    public static String formatDateTime(LocalDateTime time, String format) {
        return formatDate(time, format);
    }

    public static String formatDate(LocalDate date) {
        return formatDate(date, NORM_DATE_PATTERN);
    }

    public static String formatDate(LocalDate date, String format) {
        return null == date ? null : format(date, DateTimeFormatter.ofPattern(format));
    }

    public static String formatDate(TemporalAccessor time, String format) {
        if (null == time) {
            return null;
        } else if (!(time instanceof DayOfWeek) &&
                !(time instanceof Month) &&
                !(time instanceof Era) && !(time instanceof MonthDay)) {
            DateTimeFormatter formatter;
            formatter = null == format ? null : DateTimeFormatter.ofPattern(format);
            return format(time, formatter);
        } else {
            return time.toString();
        }
    }

    public static LocalDateTime parseDateTime(CharSequence text) {
        return parseDateTime(text, NORM_DATETIME_PATTERN);
    }

    public static LocalDateTime parseDateTime(CharSequence text, String format) {
        if (null == text || text.length() == 0) {
            return null;
        } else {
            DateTimeFormatter formatter;
            formatter = DateTimeFormatter.ofPattern(format);
            return of(formatter.parse(text));
        }
    }

    public static LocalDate parseDate(CharSequence text) {
        return parseDate(text, NORM_DATE_PATTERN);
    }

    public static LocalDate parseDate(CharSequence text, String format) {
        return null == text ? null : parseDate(text, DateTimeFormatter.ofPattern(format));
    }

    public static LocalDate parseDate(CharSequence text, DateTimeFormatter formatter) {
        if (null == text) {
            return null;
        } else {
            return null == formatter ? LocalDate.parse(text) : ofDate(formatter.parse(text));
        }
    }

    public static LocalDate ofDate(TemporalAccessor temporalAccessor) {
        if (null == temporalAccessor) {
            return null;
        } else if (temporalAccessor instanceof LocalDateTime) {
            return ((LocalDateTime) temporalAccessor).toLocalDate();
        } else {
            return temporalAccessor instanceof Instant ? of(temporalAccessor).toLocalDate()
                    : LocalDate.of(
                    getDateField(temporalAccessor, ChronoField.YEAR),
                    getDateField(temporalAccessor, ChronoField.MONTH_OF_YEAR),
                    getDateField(temporalAccessor, ChronoField.DAY_OF_MONTH));
        }
    }

    public static LocalDateTime of(TemporalAccessor temporalAccessor) {
        if (null == temporalAccessor) {
            return null;
        } else if (temporalAccessor instanceof LocalDate) {
            return ((LocalDate) temporalAccessor).atStartOfDay();
        } else if (temporalAccessor instanceof Instant) {
            return LocalDateTime.ofInstant((Instant) temporalAccessor, ZoneId.systemDefault());
        } else {
            return temporalAccessor instanceof ZonedDateTime ? ((ZonedDateTime) temporalAccessor).toLocalDateTime()
                    : LocalDateTime.of(
                    getDateField(temporalAccessor, ChronoField.YEAR),
                    getDateField(temporalAccessor, ChronoField.MONTH_OF_YEAR),
                    getDateField(temporalAccessor, ChronoField.DAY_OF_MONTH),
                    getDateField(temporalAccessor, ChronoField.HOUR_OF_DAY),
                    getDateField(temporalAccessor, ChronoField.MINUTE_OF_HOUR),
                    getDateField(temporalAccessor, ChronoField.SECOND_OF_MINUTE),
                    getDateField(temporalAccessor, ChronoField.NANO_OF_SECOND));
        }
    }

    public static int getDateField(TemporalAccessor temporalAccessor, TemporalField field) {
        return temporalAccessor.isSupported(field) ? temporalAccessor.get(field) : (int) field.range().getMinimum();
    }

    public static String format(TemporalAccessor time, DateTimeFormatter formatter) {
        if (null == time) {
            return null;
        } else if (time instanceof Month) {
            return time.toString();
        } else {
            if (null == formatter) {
                formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
            }

            try {
                return formatter.format(time);
            } catch (UnsupportedTemporalTypeException var3) {
                if (time instanceof LocalDate && var3.getMessage().contains("HourOfDay")) {
                    return formatter.format(((LocalDate) time).atStartOfDay());
                } else if (time instanceof LocalTime && var3.getMessage().contains("YearOfEra")) {
                    return formatter.format(((LocalTime) time).atDate(LocalDate.now()));
                } else if (time instanceof Instant) {
                    return formatter.format(((Instant) time).atZone(ZoneId.systemDefault()));
                } else {
                    throw var3;
                }
            }
        }
    }
}
